package com.wyp168.socket.QQ.qqserver.services;

import com.wyp168.socket.QQ.qqclient.common.Message;
import com.wyp168.socket.QQ.qqclient.common.User;
import com.wyp168.socket.QQ.qqclient.common.constant.MessageType;
import com.wyp168.socket.QQ.qqserver.QQServer;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @ClassName ServerConnectClientThread
 * @Title 该类对应的对象和某个客户端保持socket通讯
 * @Author wyp168
 * @Date 2022/10/30 16:18
 */
public class ServerConnectClientThread extends Thread {
    private Socket socket;
    private User user;

    public ServerConnectClientThread(Socket socket, User user) {
        this.socket = socket;
        this.user = user;
    }

    public Socket getSocket() {
        return socket;
    }

    @Override
    public void run() { //这里线程处于run的状态，可以发送/接收消息
        while (true) {
            try {
                System.out.println("服务端和客户端(" + user.getUserId() + ")保持通讯， 读取/发送消息");
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                Message message = (Message) ois.readObject();

                if (message.getMessageType().equals(MessageType.MESSAGE_GET_ONLINE_USERS)) {    //客户端请求获取所有在线用户信息
                    //客户端请求获得在线用户列表
                    System.out.println(message.getSender() + "--请求获取在线用户列表");
                    String onlineUsers = ManagerClientSocketThread.getOnlineUsers();
                    //构建一个Message对象，返回给客户端
                    Message msg = new Message();
                    msg.setMessageType(MessageType.MESSAGE_RET_ONLINE_USERS);
                    msg.setContent(onlineUsers);
                    msg.setGetter(message.getSender());
                    //返回给客户端
                    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                    oos.writeObject(msg);
                } else if (message.getMessageType().equals(MessageType.MESSAGE_COMMON_MES)) {   //私发消息
                    //根据message 对象 获取getterId， 然后再得到对应线程
                    ServerConnectClientThread serverConnectClientThread = ManagerClientSocketThread.getServerConnectClientThread(message.getGetter());
                    if(!ManagerClientSocketThread.getAllExcludeBySenderId("").contains(message.getGetter())) { //如果用户userId对应的线程为空，则说明目标用户尚未登陆，遂将消息存放在离线数据库offLineDb中
//                        QQServer.offLineDb.getOrDefault(message.getGetter(), new ArrayList<>()).add(message);
                        ArrayList<Message> userOffLineMessages = QQServer.offLineDb.getOrDefault(message.getGetter(), new ArrayList<>());
                        if (userOffLineMessages.size() == 0) {
                            userOffLineMessages.add(message);
                            QQServer.offLineDb.put(message.getGetter(), userOffLineMessages);
                        } else {
                            QQServer.offLineDb.get(message.getGetter()).add(message);
                        }
                        continue;
                    }
                    //得到对应socket的对象输出流， 将message对象转发给指定的客户端
                    ObjectOutputStream oos = new ObjectOutputStream(serverConnectClientThread.getSocket().getOutputStream());
                    oos.writeObject(message);   //**转发，本次项目架构没采用数据库，因此只支持在线的对象发送消息**
                } else if (message.getMessageType().equals(MessageType.MESSAGE_SEND_TO_ALL)) {  //群发消息功能
                    //获取到所有在线用户中 除了发送者用户的其他用户id
                    List<String> allExcludeBySenderId = ManagerClientSocketThread.getAllExcludeBySenderId(message.getSender());
                    //遍历所有用户id，根据用户id获取对应socket，并将消息分发给所有的接受者
                    for (String getterId : allExcludeBySenderId) {
                        if(!ManagerClientSocketThread.getAllExcludeBySenderId("").contains(getterId)) { //如果用户userId对应的线程为空，则说明目标用户尚未登陆，遂将消息存放在离线数据库offLineDb中
//                        QQServer.offLineDb.getOrDefault(message.getGetter(), new ArrayList<>()).add(message);
                            ArrayList<Message> userOffLineMessages = QQServer.offLineDb.getOrDefault(message.getGetter(), new ArrayList<>());
                            if (userOffLineMessages.size() == 0) {
                                userOffLineMessages.add(message);
                                QQServer.offLineDb.put(message.getGetter(), userOffLineMessages);
                            } else {
                                QQServer.offLineDb.get(message.getGetter()).add(message);
                            }
                            continue;
                        }
                        ObjectOutputStream oos =
                                new ObjectOutputStream(ManagerClientSocketThread.getServerConnectClientThread(getterId).getSocket().getOutputStream());

                        oos.writeObject(message);
                    }
                } else if (message.getMessageType().equals(MessageType.MESSAGE_SEND_FILE)) {    //发送文件的方法
                    ObjectOutputStream oos = null;
                    oos = new ObjectOutputStream(ManagerClientSocketThread.getServerConnectClientThread(message.getGetter()).getSocket().getOutputStream());
                    if(!ManagerClientSocketThread.getAllExcludeBySenderId("").contains(message.getGetter())) { //如果用户userId对应的线程为空，则说明目标用户尚未登陆，遂将消息存放在离线数据库offLineDb中
//                        QQServer.offLineDb.getOrDefault(message.getGetter(), new ArrayList<>()).add(message);
                        ArrayList<Message> userOffLineMessages = QQServer.offLineDb.getOrDefault(message.getGetter(), new ArrayList<>());
                        if (userOffLineMessages.size() == 0) {
                            userOffLineMessages.add(message);
                            QQServer.offLineDb.put(message.getGetter(), userOffLineMessages);
                        } else {
                            QQServer.offLineDb.get(message.getGetter()).add(message);
                        }
                        continue;
                    }
                    oos.writeObject(message);
                } else if (message.getMessageType().equals(MessageType.MESSAGE_CLIENT_EXIT)) {   //客户端请求退出
                    //客户端请求退出系统
                    System.out.println(message.getSender() + " --请求退出系统");
                    //从客户端线程中移除指定userId的线程
                    boolean isLogout = ManagerClientSocketThread.removeThread(user.getUserId());
                    //关闭socket
                    socket.close();

                    if (isLogout) {
                        System.out.println(user.getUserId() + " --用户已经安全退出...");
                    } else {
                        System.out.println(user.getUserId() + " --用户退出异常...");
                    }
                    //退出循环
                    break;
                }
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            }

        }
    }
}
